package fr.vod.videoShareUcp;



import android.app.ActionBar;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.MediaController;
import android.widget.ScrollView;
import android.widget.TextView;
import fr.vod.demo.videoshareUcp.R;
import fr.vod.ihm.adapter.MyVideoView;
import fr.vod.ihm.adapter.MyVideoView.PlayPauseListener;
import fr.vod.ihm.adapter.MyVideoView.SeekListener;
import fr.vod.ihm.adapter.VideoController;
import fr.vod.net.NetworkWatcher;
import fr.vod.threads.ServiceMulticastVideo;
import fr.vod.util.LogHelper;

public class MainActivity extends Activity {
	
	
	private MyVideoView vv;
	private MyVideoView vvfull;
	private VideoController vc;
	private MediaController mc;
	
	private ScrollView scrollViewSended;
	private ScrollView scrollViewReceived;
	
	private TextView textViewMessageSended;
	private TextView textViewMessageReceived;
	
	private TextView textViewTotalBytesSended;
	private TextView textViewTotalBytesReceived;
	private TextView textViewTimeElapsed;
	
	private TextView tvDownloadSpeed;
	private TextView tvUploadSpeed;
	
	private ActionBar actionBar;
	
	public static NetworkWatcher networkWatcher;
	
	private Messenger serviceMessenger;
	
	private boolean isFullScreenMode;
	private boolean showActionBar;
	
	/// tag des logs
	private final static String logTag = MainActivity.class.getName();
		
	// TODO change path before commit
	private final String VIDEO_PATH = Environment.getExternalStorageDirectory().getPath() + "/Movies/Star.Wars.Episode.2.Attack.of.the.Clones.2002.1080p.BrRip.x264.BOKUTOX.YIFY.mp4";
	
	/// flag indiquant si le service est binde avec l'activite
	boolean flagBind = false;
	
	public boolean binded = false;
	
	/// Instance "attrapant" les messages venant du service
	Messenger messenger = new Messenger(new IncomingHandler());
	Intent serviceIntent;
	
	/// indique le type du message entrant
	static public final int MESSAGE_INIT=1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.activity_main);
		initUIElement();
		networkWatcher = new NetworkWatcher().startWatching();
		serviceIntent = new Intent(this, ServiceMulticastVideo.class);
		// bind pour echanger des messages
		startService(serviceIntent);
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		binded = bindService(serviceIntent, serviceConn, Context.BIND_AUTO_CREATE);
		
		
		if (binded == true) {
			LogHelper.information(logTag, "Service correctly binded.");
			
		}
		else
			LogHelper.erreur(logTag, "Activity not binded to service");
	}


	private void initUIElement() {
		
		scrollViewSended = (ScrollView)findViewById(R.id.scrollViewSending);
		scrollViewReceived = (ScrollView)findViewById(R.id.scrollViewReceiving);

		textViewMessageSended = (TextView)findViewById(R.id.textViewScrollSend);
		textViewMessageReceived = (TextView)findViewById(R.id.textViewScrollReceice);		
		
		textViewTotalBytesSended = (TextView)findViewById(R.id.byteSended);
		textViewTotalBytesReceived = (TextView)findViewById(R.id.byteReceived);
		
		textViewTimeElapsed = (TextView)findViewById(R.id.timeElapsed);
		tvDownloadSpeed = (TextView)findViewById(R.id.downloadSpeed);
		tvUploadSpeed = (TextView)findViewById(R.id.uploadSpeed);
		
		vv = (MyVideoView)findViewById(R.id.videoView1);
		vv.setZOrderOnTop(true);
		vv.setVideoPath(VIDEO_PATH);
		
		vc = new VideoController(MainActivity.this);
		vc.setActivated(false);
		vc.setAnchorView(findViewById(R.id.mediaController));
		
		vc.fullScreenButton.setOnClickListener(new OnClickListener() {
			
			private int currentVideoPosition;
			
			@Override
			public void onClick(View v) {
				// appui sur le bouton fullscreen
				
				isFullScreenMode = true;
				currentVideoPosition = vv.getCurrentPosition();
				mc = new MediaController(MainActivity.this);
				actionBar = getActionBar();
				actionBar.hide();
				setContentView(R.layout.full_screen);
				vc.fullScreenButton.setVisibility(View.INVISIBLE);
				vc.setVisibility(View.INVISIBLE);
				mc.setVisibility(View.VISIBLE);
				vvfull = (MyVideoView) findViewById(R.id.videoViewFull);				
				vvfull.setMediaController(mc);
				mc.setMediaPlayer(vvfull);
				vvfull.requestFocus();
				
				
				if(!VIDEO_PATH.isEmpty()){
					vvfull.setVideoPath(VIDEO_PATH);
					vvfull.start();
					vvfull.seekTo(currentVideoPosition);
				}
				
				
				vvfull.setPlayPauseListener(new PlayPauseListener() {
					@Override
					public void onPlay() {
						textViewMessageSended.append("PLAY\n");
						scrollViewSended.fullScroll(ScrollView.FOCUS_DOWN);
						sendMessageToService("PLAY");
					}
					
					@Override
					public void onPause() {
						textViewMessageSended.append("PAUSE\n");
						scrollViewSended.fullScroll(ScrollView.FOCUS_DOWN);
						sendMessageToService("PAUSE");
					}
				});
				vvfull.setSeekListener(new SeekListener() {

			        @Override
			        public void onSeekTo(boolean ffwdrwd) {
			            if(ffwdrwd){
			            	LogHelper.information(logTag, "backWard");
			            	sendMessageToService("TIME");
			            }
			            else{
			            	LogHelper.information(logTag, "forWard");
			            	sendMessageToService("TIME");
			            }             
			        }
			     });
				// Permet d'afficher les menu du haut et bas
				 vvfull.setOnTouchListener(new OnTouchListener() {
						@Override
						public boolean onTouch(View v, MotionEvent event) {
							actionBar = getActionBar();
							if(showActionBar){
								actionBar.setDisplayHomeAsUpEnabled(true);
								actionBar.show();
								showActionBar = false;
							}
							else {
								actionBar.hide();
								showActionBar = true;
							}
							return false;
						}
					});	
			}
		});
	
		vv.setMediaController(vc);
		vv.setOnTouchListener(new OnTouchListener() {
			// Permet d'afficher les menu du haut et bas
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (vc.isActivated()){
					vc.setVisibility(View.INVISIBLE);
					vc.show(200);
					vc.setActivated(false);
				}
				else {
					vc.setActivated(true);
					vc.setVisibility(View.VISIBLE);
					vc.show(200);
					
				}
				return false;
			}
		});
		
		vv.setPlayPauseListener(new PlayPauseListener() {
			@Override
			public void onPlay() {
				LogHelper.information("onPlay", "play");
				sendMessageToService("PLAY");
			}
			
			@Override
			public void onPause() {
				LogHelper.information("onPause", "pause");
				sendMessageToService("PAUSE");
			}
		});
		vv.setSeekListener(new SeekListener() {

	        @Override
	        public void onSeekTo(boolean ffwdrwd) {
	            if(ffwdrwd){
	            	LogHelper.information(logTag, "backWard");
	            	sendMessageToService("TIME");
	            }
	            else{
	            	LogHelper.information(logTag, "forWard");
	            	sendMessageToService("TIME");
	            }             
	        }

	    });
	}

    private void sendMessageToService(String message) {
    	Message msg = Message.obtain(null, ServiceMulticastVideo.MESSAGE_CMD, 0, 0);
    	
    	Bundle bundle = msg.getData();
    	bundle.putString("CMD", message);
    	
    	if(vvfull!=null){
    		bundle.putInt("TIME", vvfull.getCurrentPosition());
    		bundle.putLong("TIMESTAMP", System.currentTimeMillis());
    	}
    	else {
    		bundle.putInt("TIME", vv.getCurrentPosition());
    		bundle.putLong("TIMESTAMP", System.currentTimeMillis());
    		
    	}
    	try {
    		textViewMessageSended.append("-->"+msg.getData().toString().substring("bundle".length())+"\n");
    		scrollViewSended.fullScroll(ScrollView.FOCUS_DOWN);
			serviceMessenger.send(msg);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
    	
    	updateTextViewInfo();
	}
    
    
	

	/**
	 * Call back du bind avec le service
	 * 
	 * L'envoi du message du service est fait 
	 * dans le call back
	 */
	private  ServiceConnection serviceConn = new ServiceConnection() {

        
        public void onServiceConnected(ComponentName className,
                IBinder serviceBinder) {
    		LogHelper.information(logTag, "onServiceConnected");	
        	
    		// Recuperation du messenger
    		serviceMessenger = new Messenger(serviceBinder);
            
            flagBind = true;
            
            // preparation du message
             Message msg = Message.obtain(null, ServiceMulticastVideo.MESSAGE_TYPE, 0, 0);

             // enregistrement du handler de l'activite
             msg.replyTo = messenger;
            		 
            try {
            	serviceMessenger.send(msg);
            	LogHelper.information(logTag, "Message sended : " + msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            
        }
        

        public void onServiceDisconnected(ComponentName arg0) {
    		LogHelper.information(logTag, "onServiceDisconnected");	

    		flagBind = false;

        }
	};
	
	public void updateTextViewInfo() {
		//System.out.println("updateTextViewInfo()");
		tvDownloadSpeed.setText(getString(R.string.download_speed) + String.valueOf(networkWatcher.getDownloadSpeed())+" o/s");
    	tvUploadSpeed.setText(getString(R.string.upload_speed) + String.valueOf(networkWatcher.getUploadSpeed())+" o/s");
    	textViewTimeElapsed.setText(getString(R.string.time_elapsed) + String.valueOf(networkWatcher.getTimeElapsed())+" s");
    	textViewTotalBytesSended.setText(getString(R.string.byte_sended) + String.valueOf(networkWatcher.getTotalBytesSended())+" o");
    	textViewTotalBytesReceived.setText(getString(R.string.byte_received) + String.valueOf(networkWatcher.getTotalBytesReceived())+" o");
	}
	
	/**
	 * Handler des messages entrant
	 *
	 */
    class IncomingHandler extends Handler {
    	
        
        IncomingHandler(){
    		LogHelper.entree(logTag, "IncomingHandler");	
        }
        
        @Override
        public void handleMessage(Message msg) {           	
           	Bundle bundle = msg.getData();
           	updateTextViewInfo();
            switch (msg.what) {
            case 	MESSAGE_INIT:
            	String incomingMessage = bundle.getString("flag");
            	LogHelper.information(logTag, "message = " + incomingMessage);
            	
            	break;
            case ServiceMulticastVideo.MESSAGE_CMD:
            	String cmd = bundle.getString("CMD");
            	textViewMessageReceived.append("<--"+bundle.toString().substring("bundle".length())+"\n");
				scrollViewReceived.fullScroll(ScrollView.FOCUS_DOWN);
            	if (cmd.contains("PLAY")) {
            		LogHelper.information(logTag, "PLAY received from Service");
            		String str[] = cmd.split("\\|");
            		for (int i = 0; i < str.length; i ++) {
            			LogHelper.information(logTag, "str["+i+"] = " + str[i]);
            		}
            		long delay = (System.currentTimeMillis() - Long.valueOf(str[2]));
            		LogHelper.information(logTag, "Le délai est donc de : " + delay + " ns");
            		vv.seekToFromHandler(Integer.valueOf(str[1]) + (int)delay);
            		vv.startFromHandler();
            		if(vvfull != null){
            			vvfull.startFromHandler();
            			vvfull.seekToFromHandler(Integer.valueOf(str[1]) + (int)delay);
            		}
            		
            	}
            	else if (cmd.contains("PAUSE")) {
            		LogHelper.information(logTag, "PAUSE received from Service");
            		String str[] = cmd.split("\\|");
            		for (int i = 0; i < str.length; i ++) {
            			LogHelper.information(logTag, "str["+i+"] = " + str[i]);
            		}
            		long delay = (System.currentTimeMillis() - Long.valueOf(str[2]));
            		LogHelper.information(logTag, "Le délai est donc de : " + delay + " ms");
            		vv.seekToFromHandler(Integer.valueOf(str[1]) + (int)delay);
            		vv.pauseFromHandler();
            		if(vvfull != null){
            			//vv.seekToFromHandler(Integer.valueOf(str[1]) + (int)delay);
            			vvfull.pauseFromHandler();
            		}
            	}
            	else if (cmd.contains("TIME")){
            		LogHelper.information(logTag, "TIME received from Service");
            		String str[] = cmd.split("\\|");
            		for (int i = 0; i < str.length; i ++) {
            			LogHelper.information(logTag, "str["+i+"] = " + str[i]);
            		}
            		long delay = (System.currentTimeMillis() - Long.valueOf(str[2]));
            		LogHelper.information(logTag, "Le délai est donc de : " + delay + " ms");
            		vv.seekToFromHandler(Integer.valueOf(str[1]) + (int)delay);
            		if(vvfull != null){
            			vvfull.seekToFromHandler(Integer.valueOf(str[1]) + (int)delay);
            		}
            	}
            	break;
            	
            case ServiceMulticastVideo.MESSAGE_STAT : 
            	break;
            	
            default:
               super.handleMessage(msg);
               break;
            }
        }
    }	
    
   @Override
    public void onBackPressed() {
    	LogHelper.information(logTag, "backPressed");
    	super.onBackPressed();
    	if(isFullScreenMode){
    		int saveTimeVideo = vvfull.getCurrentPosition();
	    	setContentView(R.layout.activity_main);
	    	initUIElement();
	    	actionBar.setDisplayHomeAsUpEnabled(false);
	    	isFullScreenMode=false;
	    	System.out.println("test "+saveTimeVideo);
	    	vv.seekTo(saveTimeVideo);
	    	vv.start();
	    	
    	}
    	else {
    		LogHelper.information(logTag,"else backPressed");
    	}
    	
    	
    }
    
    @Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	    // Respond to the action bar's Up/Home button
	    case android.R.id.home:
	    	int saveTimeVideo = vvfull.getCurrentPosition();
	    	setContentView(R.layout.activity_main);
	    	initUIElement();
	    	actionBar.setDisplayHomeAsUpEnabled(false);
	    	isFullScreenMode=false;
	    	System.out.println("test "+saveTimeVideo);
	    	vv.seekTo(saveTimeVideo);
	    	vv.start();
	        return true;
	    
	    default:
	    	break;
	    }
	    return super.onOptionsItemSelected(item);
	}

}
